import { createStore, Store, useStore as useVuexStore } from 'vuex'
import { RouteRecordRaw } from 'vue-router'
import { IRootState, IStoreType } from './types'
import projectSetting from '@/settings/projectSetting'
import { PermissionModeEnum } from '@/settings/types'
import {
  recurseFilterRoute,
  transformObjToRoute,
  flatMultiLevelRoutes
} from '@/utils/helper/routeHelper'
import { transformRouteToMenu, getAllIframes } from '@/utils/helper/menuHelper'
import sysCache from '@/utils/cache'
import { getPermCode } from '@/service/user/user'

import app from './app/app'
import tags from './tags/tags'
import login from './login/login'

const store = createStore<IRootState>({
  state() {
    return {
      // 菜单列表
      menuList: [],
      // 保存所有的iframe
      iframeList: [],
      // 后台权限模式下获取到的用户的按钮级权限code集合
      permCodeList: []
    }
  },
  mutations: {
    setMenuList(state, menuList: any) {
      state.menuList = menuList
      sysCache.localCache.setCache('userMenus', menuList)
    },
    setIframeList(state, iframeList: any) {
      state.iframeList = iframeList
    },
    setPermCodeList(state, permCodeList: string[]) {
      state.permCodeList = permCodeList
    }
  },
  actions: {
    // 获取用户的权限code集合
    async changePermissionCode({ state, commit }) {
      const { data: codeList } = await getPermCode(state.login.userInfo.id)
      commit('setPermCodeList', codeList)
      return codeList
    },
    // 将菜单转化为路由
    async buildRoutesAction({ state, dispatch, commit }) {
      let routes: RouteRecordRaw[] = []

      // 获取系统的权限模式
      const permissionMode = projectSetting.permissionMode

      if (permissionMode === PermissionModeEnum.ROLE) {
        // 1.先去加载系统中默认所有的routes
        const allRoutes: RouteRecordRaw[] = []
        // 递归获取router/modules目录下的所有以.ts文件结尾的暴露出来的模块
        const routeFiles = require.context('../router/modules', true, /\.ts/)
        routeFiles.keys().forEach((key) => {
          const route = require('../router/modules' + key.split('.')[1])
          allRoutes.push(route.default)
        })

        // 2、获取用户的角色列表
        const roleList = state.login.roleList

        // 3、通过用户角色去遍历路由表，获取该角色可以访问的路由表，生成新的路由表
        routes = recurseFilterRoute(allRoutes, roleList)

        // 4、将路由转化为menu
        const menuList = transformRouteToMenu(routes)
        // 5、根据meta中配置的orderNo字段对菜单进行排序
        menuList.sort((a, b) => {
          return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0)
        })
        // 6、将用户菜单保存
        commit('setMenuList', menuList)
        // 7、从menuList中取出所有的iframe
        const iframeList = getAllIframes(menuList)
        commit('setIframeList', iframeList)

        // 8、路由扁平化处理，将多级路由拉平，解决keep-alive组件在多级路由情况下不生效的问题
        routes = flatMultiLevelRoutes(routes)
      } else if (permissionMode === PermissionModeEnum.BACK) {
        // 1、获取用户菜单树
        const backMenuTree = await dispatch('login/getUserMenus')
        // 获取用户的权限code
        await dispatch('changePermissionCode')

        // 2、将后台获取的用户菜单树转化为routes
        routes = transformObjToRoute(backMenuTree)
        // 3、将路由转化为menu
        const menuList = transformRouteToMenu(routes)
        // 4、将用户菜单保存
        commit('setMenuList', menuList)
        // 5、从menuList中取出所有的iframe
        const iframeList = getAllIframes(menuList)
        commit('setIframeList', iframeList)

        // 6、路由扁平化处理，将多级路由拉平，解决keep-alive组件在多级路由情况下不生效的问题
        routes = flatMultiLevelRoutes(routes)
      }

      return routes
    }
  },
  modules: {
    app,
    tags,
    login
  }
})

export function setupStore() {
  store.dispatch('login/loadLocalLogin')
}

export function useStore(): Store<IStoreType> {
  return useVuexStore()
}

export default store
